/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.pa165.machineryrental.service.impl;

import cz.muni.fi.pa165.machineryrental.converters.RentalDTOConverter;
import cz.muni.fi.pa165.machineryrental.dao.CustomerDAO;
import cz.muni.fi.pa165.machineryrental.dao.MachineDAO;
import cz.muni.fi.pa165.machineryrental.dao.RentalDAO;
import cz.muni.fi.pa165.machineryrental.dto.CustomerDTO;
import cz.muni.fi.pa165.machineryrental.dto.MachineDTO;
import cz.muni.fi.pa165.machineryrental.dto.RentalDTO;
import cz.muni.fi.pa165.machineryrental.entities.Customer;
import cz.muni.fi.pa165.machineryrental.entities.Machine;
import cz.muni.fi.pa165.machineryrental.entities.Rental;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author David Katuscak, 359273
 */
@Service("RentalService")
public class RentalServiceImpl {

    @Autowired
    private CustomerDAO customerDAO;
    @Autowired
    private MachineDAO machineDAO;
    @Autowired
    private RentalDAO rentalDAO;

    @Autowired
    public RentalServiceImpl(RentalDAO rentalDAO, CustomerDAO customerDAO, MachineDAO machineDAO) {
        if (rentalDAO == null) {
            throw new IllegalArgumentException("Given RentalDAO cannot be null.");
        }
        this.rentalDAO = rentalDAO;
        
        if (customerDAO == null) {
            throw new IllegalArgumentException("Given CustomerDAO cannot be null.");
        }
        this.customerDAO = customerDAO;
        
        if (machineDAO == null) {
            throw new IllegalArgumentException("Given MachineDAO cannot be null.");
        }
        this.machineDAO = machineDAO;
    }

    /**
     * @see cz.muni.fi.pa165.machineryrental.service.RentalService#getById(long) 
     */
    @Transactional(readOnly = true)
    public RentalDTO getById(long id) {
        if (id < 0) {
            throw new IllegalArgumentException("negative id");
        }

        Rental rental = rentalDAO.getById(id);
        if (rental == null) {
            return null;
        }
        return RentalDTOConverter.toDTO(rental);
    }

    /**
     * @see cz.muni.fi.pa165.machineryrental.service.RentalService#create(RentalDTO) 
     */
    @Transactional
    public void create(RentalDTO rental) {
        if (rental == null) {
            throw new IllegalArgumentException("null rental");
        }
        Rental entity = RentalDTOConverter.toEntity(rental);
        rentalDAO.create(entity);
    }

    /**
     * @see cz.muni.fi.pa165.machineryrental.service.RentalService#update(RentalDTO)  
     */
    @Transactional
    public void update(RentalDTO rental) {
        if (rental == null) {
            throw new IllegalArgumentException("null rental");
        }
        if (rental.getId() <= 0) {
            throw new IllegalArgumentException("rental unexists");
        }
        Rental entity = rentalDAO.getById(rental.getId());
        //entity.setCustomer(rental.getCustomer());
        //entity.setMachine(rental.getMachine());
        entity.setDateOfRent(rental.getDateOfRent());
        entity.setDateOfReturn(rental.getDateOfReturn());
        entity.setDuration(rental.getDuration());

        rentalDAO.update(entity);
    }

    /**
     * @see cz.muni.fi.pa165.machineryrental.service.RentalService#remove(RentalDTO) 
     */
    @Transactional
    public void remove(RentalDTO rental) {
        if (rental == null) {
            throw new IllegalArgumentException("null rental");
        }
        if (rental.getId() <= 0) {
            throw new IllegalArgumentException("rental unexists");
        }

        Rental entity = rentalDAO.getById(rental.getId());
        rentalDAO.remove(entity);
        rental.setId(0);
    }

    /**
     * @see cz.muni.fi.pa165.machineryrental.service.RentalService#findAll()  
     */
    @Transactional
    public List<RentalDTO> findAll() {
        List<Rental> rentals = rentalDAO.findAll();

        List<RentalDTO> result = new ArrayList<RentalDTO>();
        for (Rental r : rentals) {
            result.add(RentalDTOConverter.toDTO(r));
        }
        return result;
    }

    /**
     * @see cz.muni.fi.pa165.machineryrental.service.RentalService#findByCustomer(Customer)  
     */
    @Transactional
    public List<RentalDTO> findByCustomer(CustomerDTO customer) {
        if (customer == null) {
            throw new IllegalArgumentException("null customer");
        }

        if (customer.getId() <= 0) {
            throw new IllegalArgumentException("user is not stored in system");
        }

        Customer entity = customerDAO.getById(customer.getId());

        if (entity == null) {
            throw new IllegalArgumentException("nonexisting customer");
        }

        List<Rental> rentals = rentalDAO.findByCustomer(entity);

        List<RentalDTO> result = new ArrayList<RentalDTO>();
        for (Rental r : rentals) {
            result.add(RentalDTOConverter.toDTO(r));
        }
        return result;
    }

    /**
     * @see cz.muni.fi.pa165.machineryrental.service.RentalService#findByMachine(Machine) 
     */
    @Transactional
    public List<RentalDTO> findByMachine(MachineDTO machine) {
        if (machine == null) {
            throw new IllegalArgumentException("null machine");
        }

        if (machine.getId() <= 0) {
            throw new IllegalArgumentException("machine is not stored in system");
        }

        Machine entity = machineDAO.getById(machine.getId());

        if (entity == null) {
            throw new IllegalArgumentException("nonexisting machine");
        }

        List<Rental> rentals = rentalDAO.findByMachine(entity);
        
        List<RentalDTO> result = new ArrayList<RentalDTO>();
        for (Rental r : rentals) {
            result.add(RentalDTOConverter.toDTO(r));
        }
        return result;
    }
    
    /**
     * @see cz.muni.fi.pa165.machineryrental.service.RentalService#findByIntervalOfRent(Date, Date) 
     */
    @Transactional
    public List<RentalDTO> findByIntervalOfRent(Date startDate, Date endDate) {
        List<Rental> rentals = rentalDAO.findByIntervalOfRent(startDate, endDate);

        List<RentalDTO> result = new ArrayList<RentalDTO>();
        for (Rental r : rentals) {
            result.add(RentalDTOConverter.toDTO(r));
        }
        return result;
    }
}
